home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Programming Sound Cards
/
Programming Sound Cards.iso
/
sound_30
/
data.c
next >
Wrap
C/C++ Source or Header
|
1995-01-01
|
5KB
|
238 lines
#include "midi.h"
/*
Copright 1988, G.E.S. Consulting
NORMAL MODE tutorial, RECORD and PLAY
for those who like to do all the work themselves!
NOTE:
struct eventlist {
struct event *f; ptr to first event on que
struct event *c; ptr to current event on que
struct event *l; ptr to last event on que
}
Library does NOT maintain (or have knowledge of) this structure.
You are free to devise you own way to manage event lists if you wish.
*/
main()
{
struct event *p,*op, *qp = (struct event *)0;
unsigned char r,sr;/* running status storage for get_event and show_event */
int count= 0, eventno = 0; /* counters for show_event */
init_event_list(10); /* allocate 10000 events */
mpu_init(); /* install driver */
/* tell em how to stop */
printf("Playback will begin when you hit middle C\n");
/* initialize running status */
r = 0;
sr = 0;
/* note MIDI_START is necessary to get mpu to actually do something
the first time around. see tech manual p. 20 */
mpu_control(START_RECORD|MIDI_START);
/* while MPU is still talking */
while(p = get_event(&r,10))
{
show_event(++eventno,&count,&sr,p); /* show em what they did */
if (!qp) /* chain events together */
{
qp = p;
op = p;
}
else
{
op->n = p;
op = p;
}
/* test for middle c pressed */
if (p->d.data[0] == 60 /* middle c */
&& ((p->status == 0 && r == 0x90) || p->status == 0x90))
break; /* ON or OFF */ /* all done */
}
/* tell MPU to finish up */
mpu_control(STOP_RECORD|MIDI_STOP);
/* wait for END of DATA */
while(p = get_event(&r,10))
{
show_event(++eventno,&count,&sr,p);
op->n = p;
op = p;
if (p->tbyte < 240 && p->status == 0xfc) /* end of data */
break;
}
/* reset running status */
r = 0;
/* tell MPU which tracks to play */
active_tracks(TRACK_1);
clear_play_counters();
/* start playing */
mpu_control(START_PLAY|MIDI_START);
op = qp;
/* satisy requests for data */
while(p = get_event(&r,10))
{
show_event(++eventno,&count,&sr,p);
if (p->tbyte == 255 && p->status >= 0xf0 && p->status <= 0xf7)
{
send_message(op);
op = op->n;
}
/* check for end of track */
if (p->tbyte == 255 && p->status == 0xfc) /* end of data */
break;
}
mpu_control(STOP_PLAY|MIDI_STOP);
reset_mpu();
mpu_close();
}
/* a handy routine to make an event human readable */
char *etab[] = {
"Note Off ",
"Note On ",
"Key Pres ",
"Cntrl Chg",
"Program ",
"Chan Pres",
"Ptch Weel",
"MIDI MARK"
};
/* Midi Message Length table */
int ltab[] = {2,2,2,2,1,1,2,0};
show_event(int eventno,int *rcount,unsigned char *running,struct event *p)
{
printf("Event %03d ", eventno);
if (p->tbyte < 0xf0) /* MIDI MESSAGE OR MPU MARK */
{
int etype;
int chan;
if (!p->status)
p->status = *running;
else if (p->status < 0xf0)
*running = p->status;
etype = (p->status >> 4) & 7;
if (etype == 1 && p->d.data[1] == 0)
etype--;
chan = (p->status & 7);
*rcount += p->tbyte;
printf("Timng (%02x) %3d ",p->tbyte,*rcount);
printf("%s ",etab[etype]);
switch(etype)
{
case 0:
printf("Pitch (%03d) ",p->d.data[0]);
break;
case 1:
printf("Pitch (%03d) Velocity (%03d) ",p->d.data[0],
p->d.data[1]);
break;
case 2:
printf("Pitch (%03d) Pressure (%03d) ",p->d.data[0],
p->d.data[1]);
break;
case 3:
printf("Number (%03d) Value (%03d) ",p->d.data[0],
p->d.data[1]);
break;
case 4:
printf("Number (%03d) ",p->d.data[0]);
break;
case 5:
printf("Pressure (%03d) ",p->d.data[0]);
break;
case 6:
printf("LSB (%03d) MSB (%03d) ",p->d.data[0],
p->d.data[1]);
break;
case 7:
switch(p->status)
{
case 0xf8:
printf("NOP ");
break;
case 0xf9:
*rcount = 0;
printf("Measure End ");
break;
case 0xfc:
printf("Data End ");
break;
default:
printf("INVALID! ");
}
break;
}
}
else /* MPU MESSAGE */
{
int chan = p->status & 7;
int stat = p->status;
printf("Timng (%02x) %3d ",0,*rcount);
printf("MPU MESSAGE ");
if (stat >= 0xf0 && stat <= 0xf7)
printf("Data Request: Channel %1d :",chan);
else switch(stat)
{
case 0xf8:
*rcount += 240;
printf("Timer Overflow");
break;
case 0xf9:
printf("Conductor Data Request");
break;
case 0xfa:
printf("Midi Start");
break;
case 0xfb:
printf("Midi Continue");
break;
case 0xfc:
printf("Midi Stop");
break;
case 0xfd:
printf("CLOCK to HOST");
break;
case 0xfe:
printf("ACK");
break;
case 0xff:
{
int i;
printf("SYS EX DATA[");
for (i = 0; i < p->dlen; i++)
printf("%02x",p->dlen > 4 ? p->d.dptr[i] : p->d.data[i]);
printf("]");
}
break;
}
}
printf("\n");
}